﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Interop;

namespace Stanza.Silverlight.Controls
{
    [TemplatePart(Name="popupPanelBackgroundCanvas", Type=typeof(Canvas))]
    [TemplatePart(Name="popupPanelBackgroundRect", Type=typeof(Rectangle))]
    [TemplatePart(Name="popupPanel", Type=typeof(Popup))]
    [TemplatePart(Name="popupPanelMainCanvas", Type=typeof(Canvas))]
    public class ModalPopup : ContentControl
    {
        public static readonly DependencyProperty LeftProperty =
            DependencyProperty.Register( "Left", typeof( Double ), typeof( ModalPopup ), new PropertyMetadata( 0.0 ) );
        public static readonly DependencyProperty TopProperty =
            DependencyProperty.Register( "Top", typeof( Double ), typeof( ModalPopup ), new PropertyMetadata( 0.0 ) );
        public static readonly DependencyProperty BackgroundFillProperty =
            DependencyProperty.Register( "BackgroundFill", typeof( Brush ), typeof( ModalPopup ), new PropertyMetadata( new SolidColorBrush( Colors.Gray ) ) );
        public static readonly DependencyProperty BackgroundOpacityProperty =
            DependencyProperty.Register( "BackgroundOpacity", typeof( Double ), typeof( ModalPopup ), new PropertyMetadata( 1.0 ) );

        public double Left
        {
            get { return (double)GetValue( LeftProperty ); }
            set { SetValue( LeftProperty, value ); }
        }

        public double Top
        {
            get { return (double)GetValue( TopProperty ); }
            set { SetValue( TopProperty, value ); }
        }

        public Brush BackgroundFill
        {
            get { return (Brush)GetValue( BackgroundFillProperty ); }
            set { SetValue( BackgroundFillProperty, value ); }
        }

        public double BackgroundOpacity
        {
            get { return (double)GetValue( BackgroundOpacityProperty ); }
            set { SetValue( BackgroundOpacityProperty, value ); }
        }

        private Canvas backgroundCanvas, popupCanvas;
        private Rectangle backgroundRect;
        private Popup popupPanel;
        private Size lastSize;
        private bool isEmbeddedControl;

        public ModalPopup()
        {
            DefaultStyleKey = typeof( ModalPopup );

            if( !DesignerTools.IsInDesignMode )
            {
                Loaded += new RoutedEventHandler( ModalPopup_Loaded );
                Application.Current.Host.Content.FullScreenChanged += new EventHandler( Content_FullScreenChanged );
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            backgroundCanvas = GetTemplateChild( "popupPanelBackgroundCanvas" ) as Canvas;
            backgroundRect = GetTemplateChild( "popupPanelBackgroundRect" ) as Rectangle;
            popupPanel = GetTemplateChild( "popupPanel" ) as Popup;
            popupCanvas = GetTemplateChild( "popupPanelMainCanvas" ) as Canvas;

            if( DesignerTools.IsInDesignMode && ( popupPanel != null ) && !isEmbeddedControl )
                popupPanel.IsOpen = true;
        }

        void ModalPopup_Loaded( object sender, RoutedEventArgs e )
        {
            FrameworkElement root = Application.Current.RootVisual as FrameworkElement;
            if( root != null )
            {
                root.SizeChanged += new SizeChangedEventHandler( root_SizeChanged );
                lastSize = new Size( root.Width, root.Height );
                AdjustSize( lastSize );
            }
        }

        void root_SizeChanged( object sender, SizeChangedEventArgs e )
        {
            lastSize = e.NewSize;
            AdjustSize( lastSize );
        }

        void Content_FullScreenChanged( object sender, EventArgs e )
        {
            Content c = Application.Current.Host.Content;
            if( c.IsFullScreen )
                AdjustSize( new Size( c.ActualWidth, c.ActualHeight ) );
            else
                AdjustSize( lastSize );
        }

        void AdjustSize( Size sz )
        {
            if( ( backgroundCanvas != null ) && ( backgroundRect != null ) )
            {
                Point offset = GetPanelOffset();

                Canvas.SetLeft( backgroundCanvas, -offset.X );
                Canvas.SetTop( backgroundCanvas, -offset.Y );
                backgroundCanvas.Width = sz.Width;
                backgroundCanvas.Height = sz.Height;
                backgroundRect.Width = sz.Width;
                backgroundRect.Height = sz.Height;

                if( popupPanel.IsOpen )
                {
                    Canvas.SetLeft( popupCanvas, Left - offset.X );
                    Canvas.SetTop( popupCanvas, Top - offset.Y );
                }
            }
        }

        public void OpenPopup( Point pt )
        {
            Left = pt.X;
            Top = pt.Y;
            OpenPopup();
        }

        public void OpenPopup( double ptX, double ptY )
        {
            Left = ptX;
            Top = ptY;
            OpenPopup();
        }

        public void OpenPopup()
        {
            if(( popupPanel != null ) && !isEmbeddedControl )
            {
                Point offset = GetPanelOffset();
                Canvas.SetLeft( popupCanvas, Left - offset.X );
                Canvas.SetTop( popupCanvas, Top - offset.Y );
                popupPanel.IsOpen = true;
            }
        }

        public void ClosePopup()
        {
            if( popupPanel != null )
                popupPanel.IsOpen = false;
        }

        private Point GetPanelOffset()
        {
            return this.GetAbsolutePosition();
        }

        public void SetAsEmbeddedControl()
        {
            isEmbeddedControl = true;
        }
    }
}
